16-1 jO

MATLAB 提供兩種迴圈指令,一種是 for 迴圈(For Loop),另一種是 while 迴圈(While Loop)。for 迴圈的使用語法如下:

for 變數 = 向量, 運算式 end

其中變數的值會被依次設定為向量的每一個元素值,來執行介於 for和 end 之間的運算式。另一種 for 迴圈的使用語法如下:

for 變數 = 矩陣, 運算式 end

此時變數的值會被依次設定為矩陣的每一個直行,來執行介於 for 和 end 之間的運算式。

舉例來說,下列 for 迴圈會產生一個長度為 6 的調和數列(Harmonic Sequence):

Example 1: 16-程式流程控制/forLoop01.mx = zeros(1,6); % 變數 x 是一個 1×6 大小的零矩陣 for i = 1:6 x(i) = 1/i; end disp(x) % 顯示 x format rat % 使用分數形式來顯式數值 disp(x) % 顯示 分數形式的 x 1.0000 0.5000 0.3333 0.2500 0.2000 0.1667 Columns 1 through 4 1 1/2 1/3 1/4 Columns 5 through 6 1/5 1/6

在上例中,矩陣 x 最初是一個 1×6 大小的零矩陣,在 for 迴圈中,變數 i 的值依次是 1 到 6,因此矩陣 x 的第 i 個元素的值依次被設為 1/i。其中用到的 format rat,可讓我們使用有理數形式來顯示此數列,換句話說,就是將一個數值表示成 $\frac{p}{q}$,而且 $p$ 和 $q$ 都是整數。

for 迴圈可以是多層或巢狀式(Nested)的,在下例中即產生一個 6×6 的 Hilbert 矩陣 h,其中為於第 i 列、第 j 行的元素為 :

Example 2: 16-程式流程控制/forLoop02.mh = zeros(6); % 變數 x 是一個 6×6 大小的零矩陣 for i = 1:6 for j = 1:6 h(i,j) = 1/(i+j-1); end end format rat % 使用分數形式來顯式所有數值 h % 顯示 h h = Columns 1 through 4 1 1/2 1/3 1/4 1/2 1/3 1/4 1/5 1/3 1/4 1/5 1/6 1/4 1/5 1/6 1/7 1/5 1/6 1/7 1/8 1/6 1/7 1/8 1/9 Columns 5 through 6 1/5 1/6 1/6 1/7 1/7 1/8 1/8 1/9 1/9 1/10 1/10 1/11

在上面的例子,我們使用zeros指令來預先配置(Allocate)了一個適當大小的矩陣。若不預先配置矩陣,程式仍可執行,但此時MATLAB需要動態地增加(或減小)矩陣的大小,因而降低程式的執行效率。所以在使用一個矩陣時,若能在事前知道其大小,則最好先使用zeros或ones等指令來預先配置給矩陣所需的記憶體大小。(有關程式碼的最佳化及記憶體的管理,請參見本書姊妹作「MATLAB 程式設計:進階篇」的第二章「程式碼與記憶體之最佳化」。) 在下例中,for 迴圈列出先前產生的 Hilbert 矩陣的每一直行的平方和:

Example 3: 16-程式流程控制/forLoop03.mformat short % 回到預設形式來顯式所有數值 h=magic(5); for i = h disp(norm(i)^2); % 印出每一行的平方和 end 1055 1105 1.2050e+03 1105 1055

在上例中,由於 h 是一個矩陣,所以每一次 i 的值就是矩陣 h 的一直行的內容,所以寫出來的指令特別簡潔。

若要跳出 for 迴圈,可用 break 指令。例如,若要找出最小的 n 值,滿足 n! > 10100,可輸入如下:

Example 4: 16-程式流程控制/break01.mfor i = 1:1000 if prod(1:i) > 1e100 fprintf('%g! = %e > 1e100\n', i, prod(1:i)); break; % 跳出 for 迴圈 end end70! = 1.197857e+100 > 1e100

在一個迴圈內,若要直接跳至到此迴圈下一回合的執行,可以使用 continue 指令,此指令的功能類似於 C 語言的 continue 敘述,或是 Perl 語言的 next 敘述。範例如下:

Example 5: 16-程式流程控制/continue01.mx = [1 -2 3 -4 5]; posTotal = 0; for i = 1:length(x) if x(i)<0, continue; end % 若 x(i) 小於零,直接跳到此迴圈的下一個輪迴 posTotal=posTotal+x(i); end posTotal % 顯示 posTotal 的值 posTotal = 9

在上述範例中,我們計算向量 x 的正元素的總和,因此只要遇到 x(i) 是負數,我們就可以使用 continue 指令來直接跳到此迴圈的下一個回合來繼續執行。Continue 指令是從MATLAB 6.x 才開始支援,如果你是使用 MATLAB 5.x,就沒有此指令可供使用,但是我們還是可以使用 if–then–else 的條件指令來達到相同的功能。

另一個常用到的迴圈指令是 while 迴圈,其使用語法為:

while 條件式 運算式; end

也就是說,只要條件式成立,運算式就會一再被執行。例如:先前產生調和數列的例子,亦可用 while 迴圈改寫如下:

Example 6: 16-程式流程控制/while01.mx = zeros(1,6); i = 1; while i<=6 x(i) = 1/i; i = i+1; end x % 顯示 x x = 1.0000 0.5000 0.3333 0.2500 0.2000 0.1667

若要用 while 指令找出最小的 n 值,使得 n! > 10100 ,可輸入如下:

Example 7: 16-程式流程控制/while02.mn = 1; while prod(1:n) < 1e100 n = n+1 end fprintf('%g! = %e > 1e100\n', n, prod(1:n)); n = 2 n = 3 n = 4 n = 5 n = 6 n = 7 n = 8 n = 9 n = 10 n = 11 n = 12 n = 13 n = 14 n = 15 n = 16 n = 17 n = 18 n = 19 n = 20 n = 21 n = 22 n = 23 n = 24 n = 25 n = 26 n = 27 n = 28 n = 29 n = 30 n = 31 n = 32 n = 33 n = 34 n = 35 n = 36 n = 37 n = 38 n = 39 n = 40 n = 41 n = 42 n = 43 n = 44 n = 45 n = 46 n = 47 n = 48 n = 49 n = 50 n = 51 n = 52 n = 53 n = 54 n = 55 n = 56 n = 57 n = 58 n = 59 n = 60 n = 61 n = 62 n = 63 n = 64 n = 65 n = 66 n = 67 n = 68 n = 69 n = 70 70! = 1.197857e+100 > 1e100

與前述的 for 迴圈相同,在任何時刻若要跳出 while 迴圈,亦可使用 break 指令;若要跳到下一回合的 while 迴圈,也可以使用 continue 指令。但必須特別注意的是,break 指令若用在多重迴圈中,每次只跳出包含break指令的最內部迴圈。

無論是 for 或 while 迴圈,均會降低 MATLAB 的執行速度,所以我們應盡量使用向量化的運算(Vectorized Operations)而盡量少用迴圈。(有關向量化的運算,請參見本書解妹作「MATLAB 程式設計:進階篇」的第二章「程式碼與記憶體之最佳化」。)


MATLAB程式設計:入門篇